<script lang="ts" setup>
interface Props {
  margin?: string
  size?: string
  zIndex?: number
}

const props = withDefaults(defineProps<Props>(), {
  margin: '30rpx',
  size: '80rpx',
  zIndex: 98,
})

const animation = ref<boolean>(false)

const x = ref<number>(0)
const y = ref<number>(0)

const moveX = ref<number>(0)
const moveY = ref<number>(0)

const isMove = ref<boolean>(false)

function handleMovableChange({ detail }) {
  if (detail.source === 'touch') {
    moveX.value = detail.x
    moveY.value = detail.y
    isMove.value = true
  }
}

async function handleMovableTouchend() {
  if (!isMove.value) return
  const { windowHeight, windowWidth } = uni.$uv.sys()
  const size = rpxToPx(props.size)
  const margin = rpxToPx(props.margin)
  const centerX = windowWidth / 2
  x.value = moveX.value
  y.value = moveY.value
  await sleep(100)
  if (moveX.value < centerX) {
    x.value = margin
  }
  else {
    x.value = windowWidth - margin - size
  }
  if (moveY.value >= windowHeight - margin - size) {
    y.value = windowHeight - margin - size
  }
  else if (moveY.value <= margin) {
    y.value = margin
  }
  isMove.value = false
}

function getStatusBarHeight(top = 0) {
  const { statusBarHeight } = uni.$uv.sys()
  let height = 0
  // #ifndef H5
  height = statusBarHeight > 0 ? 0 : statusBarHeight + 44
  // #endif
  return uni.$uv.addUnit(height + top, 'px')
}

function getHeight(top = 0) {
  const { windowHeight, safeAreaInsets } = uni.$uv.sys()
  const { bottom } = safeAreaInsets
  return uni.$uv.addUnit(windowHeight - rpxToPx(getStatusBarHeight(top)) - bottom, 'px')
}

async function init() {
  await nextTick()
  animation.value = false
  const { windowHeight, windowWidth } = uni.$uv.sys()
  const size = rpxToPx(props.size)
  const margin = rpxToPx(props.margin)
  x.value = windowWidth - margin - size
  y.value = windowHeight / 5 * 3
  await sleep(800)
  animation.value = true
}

onMounted(() => {
  init()
})
</script>

<template>
  <movable-area
    :style="{ top: getStatusBarHeight(), width: `${$uv.sys().windowWidth}px`, height: getHeight(), zIndex }"
    class="fixed right-200%"
  >
    <movable-view
      :x="x" :y="y" direction="all" class="fixed bottom-0 left-0 right-0"
      :style="[{ top: getStatusBarHeight(), width: size, height: size, opacity: animation ? 1 : 0 }]"
      @touchend="handleMovableTouchend" @change="handleMovableChange"
    >
      <slot />
    </movable-view>
  </movable-area>
</template>
